/**
 * 此文件用于填写 Oss Token 的接口
 */
import { ossStore, userStore } from '@/store/modules'
import { buildRoutePath, randomUUid } from '@/utils'
import { http } from '@/utils/http'

import type {
  AliOssUploadToken,
  ApiType,
  PutAliOssFileResponse
} from './model/ossModel'

enum OssApi {
  primary = '/wpc-return-visit/fileUpload/getAliOssUploadToken',
  paas = '/paas/fileUpload/getAliOssUploadToken'
}

enum OssCallBackApi {
  primary = '/wpc-return-visit/fileUpload/putAliOssFile',
  paas = '/paas/fileUpload/putAliOssFile'
}

/* 获取 oss token 信息 */
export function getAliOssUploadTokenApi(apiType: ApiType = 'primary') {
  return http.post<AliOssUploadToken>(OssApi[apiType])
}

/* 回调服务器获取文件Id */
export function getFileInfoCallback(
  data?: AnyObject,
  apiType: ApiType = 'primary'
) {
  return http.post<PutAliOssFileResponse>(OssCallBackApi[apiType], data)
}

export async function uploadFile<T extends boolean = true>(
  filePath: string,
  autoCallback?: T
): Promise<T extends true ? PutAliOssFileResponse : string>
export async function uploadFile<T extends boolean = true>(
  filePath: string,
  progressFn: (...args: unknown[]) => unknown,
  autoCallback?: T
): Promise<T extends true ? PutAliOssFileResponse : string>
export async function uploadFile(
  filePath: string,
  progressFn: ((...args: unknown[]) => unknown) | boolean = true,
  autoCallback = true
) {
  if (typeof progressFn === 'boolean') {
    autoCallback = progressFn
  }

  const { dir, accessid, host, ...OssToken } = await ossStore.getOssToken()
  const key = `${dir}${Date.now()}u${
    userStore.authInfo?.userId ?? randomUUid()
  }.${filePath.substring(filePath.lastIndexOf('.') + 1)}`

  const { statusCode, data } =
    await new Promise<UniApp.UploadFileSuccessCallbackResult>(
      (resolve, reject) => {
        const uTask = uni.uploadFile({
          url: host,
          name: 'file',
          filePath: filePath,
          formData: {
            key: key ?? undefined,
            ...OssToken,
            ossAccessKeyId: accessid
          },
          success: resolve,
          fail: reject
        })
        if (typeof progressFn === 'function') uTask.onProgressUpdate(progressFn)
      }
    )

  if (statusCode !== 204) throw Error(data)
  if (autoCallback) {
    return getFileInfoCallback({ key })
  }
  return buildRoutePath(host, key)
}
